package com.kdg.thread.consurrenttest;

import com.kdg.thread.DeadLockChecker;

import java.util.concurrent.locks.ReentrantLock;

/**
 * @author kdg
 * @description:
 * @date 2018/5/12.
 */
public class ReentLockTest implements Runnable{
    public static ReentrantLock lock1 = new ReentrantLock();
    public static ReentrantLock lock2 = new ReentrantLock();
    public static int i=0;
    int lock;

    public ReentLockTest(int lock) {
        this.lock = lock;
    }

    /**
     * 控制加锁顺序，方便构造死锁
     */
    @Override
    public void run() {
        try {
            if(lock == 1){
                lock1.lockInterruptibly();
                Thread.sleep(500);
                lock2.lockInterruptibly();
            }else{
                lock2.lockInterruptibly();
                Thread.sleep(500);
                lock1.lockInterruptibly();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            if(lock1.isHeldByCurrentThread()){
                lock1.unlock();
            }
            if(lock2.isHeldByCurrentThread()){
                lock2.unlock();
            }
            System.out.println(Thread.currentThread().getId()+":线程退出");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ReentLockTest reentLockTest = new ReentLockTest(1);
        Thread t1 = new Thread(reentLockTest);
        ReentLockTest reentLockTest1 = new ReentLockTest(2);
        Thread t2 = new Thread(reentLockTest1);
        t1.start();
        t2.start();
        Thread.sleep(1000);
        DeadLockChecker.check();
    }


    /**
     * 演示Reentrant锁的可重入锁，重复进入重复退出
     */
    /*@Override
    public void run() {
        for(int j=0;j<10000;j++){
            lock.lock();
            lock.lock();
            try {
                i++;
            } finally {
                lock.unlock();
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ReentLockTest reentLockTest = new ReentLockTest();
        Thread t1 = new Thread(reentLockTest);
        Thread t2 = new Thread(reentLockTest);
        t1.start();t2.start();
        t1.join();t2.join();
        System.out.println("finished......"+i);

    }*/
}
